package com.css.fxfzysx.modules.cztDataMange.service.impl;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson.JSONObject;
import com.css.fxfzysx.base.response.RestResponse;
import com.css.fxfzysx.constants.FxfzConstants;
import com.css.fxfzysx.constants.YNEnum;
import com.css.fxfzysx.modules.cztDataMange.constans.RedisKeyConstants;
import com.css.fxfzysx.modules.cztDataMange.entity.CbhdInfoEntity;
import com.css.fxfzysx.modules.cztDataMange.repository.SdoBuildingsRepository;
import com.css.fxfzysx.modules.cztDataMange.service.SdoBuildingsService;
import com.css.fxfzysx.modules.cztDataMange.utils.GenerationNumberUtil;
import com.css.fxfzysx.modules.cztDataMange.vo.BuildingsVo;
import com.css.fxfzysx.modules.vabStructure.vo.CrsEntiretyQueryParam;
import com.css.fxfzysx.util.*;
import com.css.fxfzysx.web.PlatformSessionContext;
import com.css.fxfzysx.zcpt.sys.entity.SUser;
import com.css.fxfzysx.zcpt.sys.service.SUserService;
import com.css.fxfzysx.zcpt.sys.service.SysRoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


@Service
@Slf4j
public class SdoBuildingsServiceImpl implements SdoBuildingsService {

    @Autowired
    private SdoBuildingsRepository sdoBuildingsRepository;

    @Resource
    private GenerationNumberUtil generationNumberUtil;

    @Autowired
    private SysRoleService roleService;

    @Value("${image.localDir}")
    private String localDir;

    @Autowired
    private SUserService sUserService;


    @Override
    public RestResponse uploadHsoBuildings(MultipartFile file) {
        try {
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
            List<Object> title = reader.readRow(1);
            String titleName = "[序号, 省份, 市, 区/县级, *结构类型, *结构类型, *设防情况, *建造年代, *用途, *用途, *层数, *烈度, *破坏程度]";
            log.info("表头:{}",title.toString());
            if (!titleName.equals(title.toString())) {
                return RestResponse.fail("导入失败，请检查表头是否改动");
            }
            List<List<Object>> read = reader.read(3, reader.getRowCount());
            if (read.size() == 0) {
                return RestResponse.fail("导入失败，表格中无数据");
            }
            //数据校验
            RestResponse rs = HsoParameterVerification(read.size(), read);
            if (rs.getCode() != 200) {
                return RestResponse.fail(rs.getMessage());
            }
            for (List<Object> objects : read) {
                CbhdInfoEntity cbhdEntity = new CbhdInfoEntity();
                cbhdEntity.setCbhdId(UUIDGenerator.getUUID());
                cbhdEntity.setProvince(objects.get(1).toString());
                cbhdEntity.setCity(objects.get(2).toString());
                cbhdEntity.setCounty(objects.get(3).toString());
                cbhdEntity.setStructureType(objects.get(4).toString());
                cbhdEntity.setStructureType1(objects.get(5).toString());
                cbhdEntity.setFortification(objects.get(6).toString());
                cbhdEntity.setYears(objects.get(7).toString());
                cbhdEntity.setUse0(objects.get(8).toString());
                cbhdEntity.setUse1(objects.get(9).toString());
                cbhdEntity.setCs(objects.get(10).toString());
                cbhdEntity.setIntensity(objects.get(11).toString());
                cbhdEntity.setDamage(objects.get(12).toString());
                cbhdEntity.setCreateUser(PlatformSessionContext.getUserID());
                String user = sUserService.getSUser(PlatformSessionContext.getUserID());
                SUser sUser = CreateGson.createGson().fromJson(user, SUser.class);
                cbhdEntity.setCreateUserName(sUser.getUserName());
                cbhdEntity.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
                cbhdEntity.setDelFlag(YNEnum.N.toString());
                cbhdEntity.setBasicLibrary(YNEnum.N.toString());
                cbhdEntity.setDataType(FxfzConstants.CZT_LSZH_INFO);
//                cbhdEntity.setOrderField(cbhdEntity.getProvince() + "-" + cbhdEntity.getCity() + "-" + cbhdEntity.getCounty()
//                        + "-" + cbhdEntity.getUse0() + "-" + cbhdEntity.getUse1() + "-" + cbhdEntity.getStructureType() + "-" + cbhdEntity.getStructureType1()
//                        + "-" + cbhdEntity.getYears() + "-" + cbhdEntity.getCs() + "-" + cbhdEntity.getFortification());
                String generationNumber = this.getNumber(RedisKeyConstants.CZT_JZWLSZH_KEY);
                String number = generationNumberUtil.getCityInitials(cbhdEntity.getProvince()) + "-" +
                        generationNumberUtil.type(cbhdEntity.getStructureType(), cbhdEntity.getStructureType1()) + "-" +
                        generationNumberUtil.getFs(cbhdEntity.getFortification()) + "-" + generationNumber;
                cbhdEntity.setNumber(number);
                sdoBuildingsRepository.saveHsoBuildings(cbhdEntity);
            }
//            Map<String, List<CbhdInfoEntity>> collect = dataList.stream().collect(Collectors.groupingBy(CbhdInfoEntity::getOrderField));
//            collect.forEach((k, v) -> {
//                String generationNumber = this.getNumber(RedisKeyConstants.CZT_JZWLSZH_KEY);
//                String[] split = k.split("-");
//                String number = generationNumberUtil.getCityInitials(split[0]) + "-" +
//                        generationNumberUtil.type(split[5], split[6]) + "-" +
//                        generationNumberUtil.getFs(split[9]) + "-" + generationNumber;
//                for (CbhdInfoEntity cbvInfoEntity : v) {
//                    cbvInfoEntity.setNumber(number);
//                    sdoBuildingsRepository.saveHsoBuildings(cbvInfoEntity);
//                }
//            });
            return RestResponse.succeed("导入成功");
        } catch (Exception e) {
            e.printStackTrace();
            return RestResponse.fail(e.getMessage());
        }
    }

    private RestResponse HsoParameterVerification(int size, List<List<Object>> data) {
        for (int i = 0; i < size; i++) {
            List<Object> objects = data.get(i);
            if (StringUtils.isBlank(objects.get(1).toString()))
                return RestResponse.fail("第" + (i + 4) + "行的{省}不能为空！");
            if (StringUtils.isBlank(objects.get(2).toString()))
                return RestResponse.fail("第" + (i + 4) + "行的{市}不能为空！");
            if (StringUtils.isBlank(objects.get(3).toString()))
                return RestResponse.fail("第" + (i + 4) + "行的{区/县级}不能为空！");
            if (StringUtils.isBlank(objects.get(4).toString()))
                return RestResponse.fail("第" + (i + 4) + "行的{结构类型}不能为空！");
            if(!objects.get(4).toString().equals("土木结构") || !objects.get(4).toString().equals("木结构") || !objects.get(4).toString().equals("钢结构") ||
            !objects.get(4).toString().equals("组合结构") || !objects.get(4).toString().equals("其他")){
                if (StringUtils.isBlank(objects.get(5).toString()))
                    return RestResponse.fail("第" + (i + 4) + "行的{结构类型}不能为空！");
            }
            if (StringUtils.isBlank(objects.get(6).toString()))
                return RestResponse.fail("第" + (i + 4) + "行的{设防情况}不能为空！");
            if (StringUtils.isBlank(objects.get(7).toString()))
                return RestResponse.fail("第" + (i + 4) + "行的{建造年代}不能为空！");
            if (StringUtils.isBlank(objects.get(8).toString()))
                return RestResponse.fail("第" + (i + 4) + "行的{用途}不能为空！");
            if (StringUtils.isBlank(objects.get(9).toString()))
                return RestResponse.fail("第" + (i + 4) + "行的{用途}不能为空！");
            if (StringUtils.isBlank(objects.get(10).toString()))
                return RestResponse.fail("第" + (i + 4) + "行的{层数}不能为空！");
            if (StringUtils.isBlank(objects.get(11).toString()))
                return RestResponse.fail("第" + (i + 4) + "行的{烈度}不能为空！");
            if (StringUtils.isBlank(objects.get(12).toString()))
                return RestResponse.fail("第" + (i + 4) + "行的{破坏程度}不能为空！");
        }
        return RestResponse.succeed();
    }

    private String getNumber(String key) {
        return generationNumberUtil.getGenerationNumber(key);
    }

    @Override
    public RestResponse updateBuildings(CbhdInfoEntity cbhdInfoEntity) {
        try {
            CbhdInfoEntity data = sdoBuildingsRepository.getBuildingsById(cbhdInfoEntity.getCbhdId());
            if (!data.getCreateUser().equals(PlatformSessionContext.getUserID())) {
                return RestResponse.fail("只能修改本人数据!");
            }
            cbhdInfoEntity.setUpdateUser(PlatformSessionContext.getUserID());
            cbhdInfoEntity.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
            sdoBuildingsRepository.updateBuildings(cbhdInfoEntity);
            return RestResponse.succeed("修改成功!");
        } catch (Exception e) {
            String errorMessage = "修改失败!";
            log.error(errorMessage, e);
            return RestResponse.fail(errorMessage);
        }
    }

    @Override
    public RestResponse deleteBuildingsById(String number) {
        try {
            boolean result = true;
            for (String id : number.split(",")) {
                result = sdoBuildingsRepository.deleteBuildingsById(id);
            }
            if (result) {
                return RestResponse.succeed("删除成功!");
            } else {
                return RestResponse.fail("删除失败!");
            }
        } catch (Exception e) {
            String errorMessage = "删除失败!";
            log.error(errorMessage, e);
            return RestResponse.fail(errorMessage);
        }
    }

    @Override
    public RestResponse queryBuildings(CbhdInfoEntity cbhdInfoEntity, HttpServletRequest request) {
        try {
            int page = Integer.valueOf(request.getParameter(PlatformPageUtils.CUR_PAGE));
            int size = Integer.valueOf(request.getParameter(PlatformPageUtils.PAGE_SIZE));
            String userID = PlatformSessionContext.getUserID();
            String role = roleService.getRoleByUserId(userID);
            List<Map> roleMaps = JSONObject.parseArray(role, Map.class);
            ArrayList<String> roleList = new ArrayList<>();
            for (Map roleMap : roleMaps) {
                String roleCode = (String) roleMap.get("roleCode");
                roleList.add(roleCode);
            }
            return RestResponse.succeed(sdoBuildingsRepository.queryBuildings(cbhdInfoEntity, page, size, roleList));
        } catch (Exception e) {
            String errorMessage = "查看失败!";
            log.error(errorMessage, e);
            return RestResponse.fail(errorMessage);
        }
    }

    @Override
    public RestResponse queryCrsBuildings(CrsEntiretyQueryParam cbhdInfoEntity, HttpServletRequest request) {
        try {
            int page = Integer.valueOf(request.getParameter(PlatformPageUtils.CUR_PAGE));
            int size = Integer.valueOf(request.getParameter(PlatformPageUtils.PAGE_SIZE));
            String userID = PlatformSessionContext.getUserID();
            String role = roleService.getRoleByUserId(userID);
            List<Map> roleMaps = JSONObject.parseArray(role, Map.class);
            /*for (Map roleMap : roleMaps) {
                String roleCode = (String) roleMap.get("roleCode");
                if (roleCode.equals(FxfzConstants.CZT_PRI_GL_ROLE) || roleCode.equals(FxfzConstants.CZT_COUN_GL_ROLE)) {
                    cbhdInfoEntity.setRole("0");
                } else {
                    cbhdInfoEntity.setRole("1");
                }
            }*/
            return RestResponse.succeed(sdoBuildingsRepository.queryCrsBuildings(cbhdInfoEntity, page, size));
        } catch (Exception e) {
            String errorMessage = "查看失败!";
            log.error(errorMessage, e);
            return RestResponse.fail(errorMessage);
        }
    }

    @Override
    public RestResponse deleteCrsById(String calId) {
        try {

        } catch (Exception e) {

        }
        return null;
    }

    @Override
    public RestResponse getBuildingsById(String buildingsId) {
        try {
            return RestResponse.succeed(sdoBuildingsRepository.getBuildingsById(buildingsId));
        } catch (Exception e) {
            String errorMessage = "查询失败!";
            log.error(errorMessage, e);
            return RestResponse.fail(errorMessage);
        }
    }

    @Override
    public RestResponse getBuildingsByNumber(String number) {
        try {
            //最终返回结果
            HashMap<String, Object> resultMap = new HashMap<>();
            LinkedHashMap<String, Object> curveMap = new LinkedHashMap<>();
            //表格数据
            List<CbhdInfoEntity> data = sdoBuildingsRepository.getBuildingsByNumber(number);
            //柱状图数据和表格数据
            Map<String, List<CbhdInfoEntity>> histogramData = data.stream().collect(Collectors.groupingBy(CbhdInfoEntity::getIntensity));
            ArrayList<BuildingsVo> buildingsVoList = new ArrayList<>();
            histogramData.forEach((k, v) -> {
                BuildingsVo buildingsVo = new BuildingsVo();
                buildingsVo.setIntensity(k);
                buildingsVo.setDataList(v);
                buildingsVoList.add(buildingsVo);
            });
            resultMap.put("data", buildingsVoList);
            Map<String, List<CbhdInfoEntity>> collect = data.stream().collect(Collectors.groupingBy(CbhdInfoEntity::getDamage));
            //折线图SD数据
            Iterator<String> iterator = collect.keySet().iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                if ("基本完好".equals(key)) {
                    iterator.remove();
                    collect.remove(key);
                }
            }
            curveMap.put("sd", processData(collect));
            //折线图MD数据
            Iterator<String> iterator1 = collect.keySet().iterator();
            while (iterator1.hasNext()) {
                String key = iterator1.next();
                if ("轻微破坏".equals(key)) {
                    iterator1.remove();
                    collect.remove(key);
                }
            }
            curveMap.put("md", processData(collect));
            //折线图ED数据
            Iterator<String> iterator2 = collect.keySet().iterator();
            while (iterator2.hasNext()) {
                String key = iterator2.next();
                if ("中等破坏".equals(key)) {
                    iterator2.remove();
                    collect.remove(key);
                }
            }
            curveMap.put("ed", processData(collect));
            //折线图C数据
            Iterator<String> iterator3 = collect.keySet().iterator();
            while (iterator3.hasNext()) {
                String key = iterator3.next();
                if ("严重破坏".equals(key)) {
                    iterator3.remove();
                    collect.remove(key);
                }
            }
            curveMap.put("c", processData(collect));
            resultMap.put("curve", curveMap);
            return RestResponse.succeed(resultMap);
        } catch (Exception e) {
            String errorMessage = "查询失败!";
            log.error(errorMessage, e);
            return RestResponse.fail(errorMessage);
        }
    }

    private HashMap<String, Object> processData(Map<String, List<CbhdInfoEntity>> collect) {
        ArrayList<CbhdInfoEntity> data6List = new ArrayList<>();
        ArrayList<CbhdInfoEntity> data7List = new ArrayList<>();
        ArrayList<CbhdInfoEntity> data7ListCopy = new ArrayList<>();
        ArrayList<CbhdInfoEntity> data8List = new ArrayList<>();
        ArrayList<CbhdInfoEntity> data8ListCopy = new ArrayList<>();
        ArrayList<CbhdInfoEntity> data9List = new ArrayList<>();
        ArrayList<CbhdInfoEntity> data9ListCopy = new ArrayList<>();
        ArrayList<CbhdInfoEntity> data10List = new ArrayList<>();
        collect.forEach((k, v) -> {
            for (CbhdInfoEntity it : v) {
                if (it.getIntensity().equals("6度(0.05g)")) {
                    data6List.add(it);
                }
                if (it.getIntensity().equals("7度(0.10g)")) {
                    data7List.add(it);
                }
                if (it.getIntensity().equals("7度(0.15g)")) {
                    data7ListCopy.add(it);
                }
                if (it.getIntensity().equals("8度(0.20g)")) {
                    data8List.add(it);
                }
                if (it.getIntensity().equals("8度(0.30g)")) {
                    data8ListCopy.add(it);
                }
                if (it.getIntensity().equals("9度(0.40g)")) {
                    data9List.add(it);
                }
                if (it.getIntensity().equals("9度(0.60g)")) {
                    data9ListCopy.add(it);
                }
                if (it.getIntensity().equals("10度(0.80g)")) {
                    data10List.add(it);
                }
            }
        });
        LinkedHashMap<String, Object> sdMap = new LinkedHashMap<>();
        if (PlatformObjectUtils.isNotEmpty(data6List)) {
            sdMap.put("0.05g", (double) Math.round(data6List.stream().map(d -> d.getParamValue()).reduce(Double::sum).get() * 100) / 100);
        }
        if (PlatformObjectUtils.isNotEmpty(data7List)) {
            sdMap.put("0.10g", (double) Math.round(data7List.stream().map(d -> d.getParamValue()).reduce(Double::sum).get() * 100) / 100);
        }
        if (PlatformObjectUtils.isNotEmpty(data7ListCopy)) {
            sdMap.put("0.15g", (double) Math.round(data7ListCopy.stream().map(d -> d.getParamValue()).reduce(Double::sum).get() * 100) / 100);
        }
        if (PlatformObjectUtils.isNotEmpty(data8List)) {
            sdMap.put("0.20g", (double) Math.round(data8List.stream().map(d -> d.getParamValue()).reduce(Double::sum).get() * 100) / 100);
        }
        if (PlatformObjectUtils.isNotEmpty(data8ListCopy)) {
            sdMap.put("0.30g", (double) Math.round(data8ListCopy.stream().map(d -> d.getParamValue()).reduce(Double::sum).get() * 100) / 100);
        }
        if (PlatformObjectUtils.isNotEmpty(data9List)) {
            sdMap.put("0.40g", (double) Math.round(data9List.stream().map(d -> d.getParamValue()).reduce(Double::sum).get() * 100) / 100);
        }
        if (PlatformObjectUtils.isNotEmpty(data9ListCopy)) {
            sdMap.put("0.60g", (double) Math.round(data9ListCopy.stream().map(d -> d.getParamValue()).reduce(Double::sum).get() * 100) / 100);
        }
        if (PlatformObjectUtils.isNotEmpty(data10List)) {
            sdMap.put("0.80g", (double) Math.round(data10List.stream().map(d -> d.getParamValue()).reduce(Double::sum).get() * 100) / 100);
        }
        return sdMap;
    }

    @Override
    public int updateBuildingsForm(List<CbhdInfoEntity> cbhList) {
        Map<String, List<CbhdInfoEntity>> collect = cbhList.stream().collect(Collectors.groupingBy(CbhdInfoEntity::getIntensity));
        for (Map.Entry<String, List<CbhdInfoEntity>> entry : collect.entrySet()) {
            List<CbhdInfoEntity> list = entry.getValue();
            double value = (double) Math.round(list.stream().map(e -> e.getParamValue()).reduce(Double::sum).get() * 100) / 100;
            boolean predict = predict(value);
            if (predict) {
                for (CbhdInfoEntity entity : list) {
                    entity.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
                    entity.setUpdateUser(PlatformSessionContext.getUserID());
                    sdoBuildingsRepository.updateBuildingsForm(entity);
                }
            } else {
                return -1;
            }
        }
        return 0;
    }

    private boolean predict(Double d) {
        if (new BigDecimal(d).compareTo(new BigDecimal(0.99)) != -1 && new BigDecimal(d).compareTo(new BigDecimal(1.01)) != 1) {
            return true;
        }
        return false;
    }

    @Override
    public RestResponse generatePictures(HttpServletRequest request) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
        String line;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        String base = sb.toString();
        if (!StringUtils.isEmpty(base)) {
            OutputStream out = null;
            try {
                String base64 = base.split(",")[1];
                byte[] bytes = new BASE64Decoder().decodeBuffer(base64);
                for (int i = 0; i < bytes.length; ++i) {
                    if (bytes[i] < 0) {
                        bytes[i] += 256;
                    }
                }
                String fileName = UUID.randomUUID().toString().replaceAll("-", "") + ".jpg";
                String realPath = localDir;
                File file = new File(realPath);
                if (!file.exists() || !file.isDirectory()) {
                    file.mkdirs();
                }
                out = new FileOutputStream(realPath + "/" + fileName);
                out.write(bytes);
                out.flush();
            } catch (Exception e) {
                log.error(e.getMessage());
                return RestResponse.succeed("图片下载失败!");
            } finally {
                if (out != null) {
                    out.close();
                }
            }
        }
        return RestResponse.succeed("图片下载成功!");
    }

    public RestResponse moveBasicLibraryByNumber(String number, String operate) {
        try {
            sdoBuildingsRepository.moveBasicLibraryByNumber(number, operate);
            return RestResponse.succeed("成功!");
        } catch (Exception e) {
            String errorMessage = "失败!";
            log.error(errorMessage, e);
            return RestResponse.fail(errorMessage);
        }
    }
}
